# 2.4 语句 ## 过程语句 `initial`、`always` 1. 在一个模块中,使用`initial`和`always`语句的次数是不受限制的;`initial`语句常用于仿真中的初始化,过程块中的语句仅执行一次;`always`块内的语句则是不断重复执行的。 2. `always`语句 1. 格式: ```verilog always @ () begin <......> end ``` 2. `always`过程语句通常是带有触发条件的,触发条件写在**敏感信号表达式**中,只有当触发条件满足时,其后的`begin-end`块语句才能被执行。 3. 敏感信号表达式又称事件表达式或敏感信号列表,即当该表达式中变量的值改变时,就会引发块内语句的执行。其中应列出影响块内取值的所有信号,若有两个或两个以上信号时,它们之间用`or`连接。举例: ```verilog @(a) // 当信号a的值发生改变 @(a or b) // 当信号a或信号b的值发生改变 @(posedge clock) // 当clock的上升沿到来时 @(negedge clock) // 当clock的下降沿到来时 @(posedge clk or negedge reset) // 当clk的上升沿或reset信号的下降沿到来 ``` 4. `posedge`和`negedge`关键字:对于时序电路,事件通常是由时钟边沿触发的,为表达边沿概念,Verilog提供了这两个关键字来描述。 5. 例:4选1数据选择器 ```verilog module mux4_1 (out, in0, in1, in2, in3, sel); output out; input in0, in1, in2, in3; input [1:0] sel; reg out; always @ (in0 or in1 or in2 or in3 or sel) case(sel) 2'b00: out=in0; 2'b01: out=in1; 2'b10: out=in2; 2'b11: out=in3; default: out=2'bx; endcase endmodule ``` 6. 例:同步置数、同步清零的计数器 ```verilog module count(out, data, load, reset, clk); output [7:0] out; input [7:0] data; input load, clk, reset; reg [7:0] out; always @ (posedge clk) begin if(!reset) out=8'h00; // 同步清0,低电平有效 else if(load) out=data; // 同步预置 else out=out+1; // 计数 end endmodule ``` ## 块语句 `begin-end` 1. 块语句是由块标志符`begin-end`的一组语句,当块语句只包含一条语句时,块标志符可以缺省。 2. `begin-end`串行块中的语句按串行方式顺序执行。比如: ```verilog begin regb=rega; regc=regb; end ``` 由于`begin-end`块内的语句顺序执行,在最后,将`regb`、`regc`的值都更新为`rega`的值,该`begin-end`块执行完后,`regb`、`regc`的值是相同的。 ## 赋值语句 `assign`、`=`、`<=` ### 1. 连续赋值语句 `assign`为持续赋值语句,主要用于对`wire`型变量的赋值。如: ```verilog wire a, b, c; assign c = a & b; ``` 在上面的赋值中,`a`、`b`、`c`三个变量皆为`wire`型变量,`a`和`b`信号的任何变化都将随时反映到`c`上来。 ### 2. 过程赋值语句 `nonblocking`、`blocking` 过程赋值语句多用于对`reg`型变量进行赋值。 1. **非阻塞(nonblocking)赋值**:符号`<=`;例如:`b<=a;` 在整个过程块结束时才完成赋值操作,即`b`的值并不是立刻就改变的。 2. **阻塞(blocking)赋值**:符号`=`;例如:`b=a;` 阻塞赋值在该语句结束时就立即完成赋值操作,即`b`的值在该条语句结束后立刻改变。如果在一个块语句中,有多条阻塞赋值语句,那么在前面的赋值语句没有完成之前,后面的语句就不能被执行,仿佛被阻塞了一样,因此称为阻塞赋值方式。 ### 3. 顺序与并发 两个或更多个`always`过程块、`assign`持续赋值语句、实例元件调用等操作都是同时执行的。在`always`模块内部,其语句如果是非阻塞赋值,也是并发执行的;而如果是阻塞赋值,则语句是按照指定的顺序执行的,语句的书写顺序对程序的执行结果有着直接的影响。 ## 条件语句 `if-else`、`case`、`casez`、`casex` ### 1. `if-else`语句 ```verilog if ; if ; else ; if ; else if ; else if ; ...... else if ; else ; ``` ### 2. `case`语句 1. `case`:全等比较,即控制表达式和分支项表达式的值各对应位必须全等 ```verilog case () key1: ; key2: ; ...... key_n: ; default: ; endcase ``` 2. `casez`:如果表达式的值的某些位是z,那么对这些位的比较就不予考虑,只对非z位进行比较。 3. `casex`:如果表达式的值的某些位是x或z,那么对这些位的比较就不予考虑,只对非x或非z位进行比较。 ## 循环语句 `for`、`forever`、`repeat`、`while` 1. `forever`:连续地执行语句;多用在initial块中, 以生成时钟等周期性波形 2. `repeat`:连续执行一条语句n次 ```verilog initial begin repeat(5) out = out + 1; end ``` 3. `while`:执行一条语句直到某个条件不满足 ```verilog initial begin i = 0; while(i < 10) i = i + 1; end ``` 4. `for`:有条件的循环语句 ```verilog initial begin for(i = 0; i < 4; i = i + 1) out = out + 1; end ```